﻿using System;

namespace _23_InterpreterPattern
{
    /// <summary>
    /// 解释器模式
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            IExpression isMale = GetMaleExpression();
            IExpression isMarriedWoman = GetMarriedWomanExpression();

            Console.WriteLine("John is male? " + isMale.Interpret("John"));
            Console.WriteLine("Julie is a married women? "
            + isMarriedWoman.Interpret("Married Julie"));
        }
        //规则：Robert 和 John 是男性
        public static IExpression GetMaleExpression()
        { 
            IExpression robert = new TerminalExpression("Robert");
            IExpression john = new TerminalExpression("John");
            return new OrExpression(robert, john);
        }

        //规则：Julie 是一个已婚的女性
        public static IExpression GetMarriedWomanExpression()
        {
            IExpression julie = new TerminalExpression("Julie");
            IExpression married = new TerminalExpression("Married");
            return new AndExpression(julie, married);
        }
    }
    public interface IExpression
    {
        public bool Interpret(string context);
    }
    public class TerminalExpression : IExpression
    {
        private string _date;
        public TerminalExpression(string date)
        {
            _date = date;
        }
        public bool Interpret(string context)
        {
            if (context.Contains(_date))
                return true;
            return false;
        }
    }
    public class OrExpression : IExpression
    {
        private IExpression _expr1 = null;
        private IExpression _expr2 = null;
        public OrExpression(IExpression expr1, IExpression expr2)
        {
            _expr1 = expr1;
            _expr2 = expr2;
        }

        public bool Interpret(string context)
        {
            return _expr1.Interpret(context) || _expr2.Interpret(context);
        }
    }
    public class AndExpression : IExpression
    {
        private IExpression _expr1 = null;
        private IExpression _expr2 = null;
        public AndExpression(IExpression expr1, IExpression expr2)
        {
            _expr1 = expr1;
            _expr2 = expr2;
        }

        public bool Interpret(string context)
        {
            return _expr1.Interpret(context) || _expr2.Interpret(context);
        }
    }

}
